﻿using System.Windows;
using DeepEarth.Core;
using System.Windows.Media;
using DeepEarth.Map.Core.Utilities;
namespace DeepEarth.Map.Core
{
    public class GlobalCelLayer : VectorCelLayer
    {
        //const double DefaultGlobalWidth = 2097152; // 2^21
        public const double DefaultGlobalWidth = 1073741824; // 2^30 (zoom level 1 is 2^9. Zoom level 21 is 2^30

        public GlobalCelLayer() : base(DefaultGlobalWidth)
        {
            this.LogicalWidth = 1.0;
            this.Origin = new Point(0, 0);
        }

        protected override bool CheckVisibility()
        {
            return true;
        }

        protected override void CalculateTransforms()
        {
            // It is possible for the user to trigger a synchronize before we're fully loaded.
            if (MapInstance == null)
            {
                return;
            }

            // calculate required scale
            double viewportWidth = MapInstance.CurrentViewportLogicalWidth;
            double currentWorldWidthAtView = MapInstance.AsFrameworkElement.ActualWidth / viewportWidth;
            CurrentScale = currentWorldWidthAtView / this.Width;


            #region start old translate calc

            //Location topleft = MapInstance.ViewportPointToLocation(new Point(0, 0));
            //Point topLeftAbsolutePixel = this.LocationToAbsolutePixel(topleft);

            //if (topleft.Latitude >= BingMapsMaxLatitiude)
            //{
            //    // If the point is out of bounds, bing maps will report the latitude as Max possible (source: Reflector)
            //    // In that case our synchronization on the Y axis will be out, so find the top point another way

            //    // 1. Get the actual pixel position of the top left corner. Normally this is 0,0 but we are in an abnormal case
            //    Point mapTopCornerCoordinateActual = MapInstance.LocationToViewportPoint(topleft);

            //    // 2. Figure out the difference between 0,0 and the actual pixel position on the large static canvas.
            //    var offset = mapTopCornerCoordinateActual.Y / currentScale;

            //    // 3. Apply the offset
            //    topLeftAbsolutePixel.Y -= offset;
            //}

            //// bing maps showing more than one complete map, favour the middle map
            //if (viewportWidth >= 1 && MapIsWrapped)
            //{
            //    // Get the center of the viewport in logical coordinates
            //    Point centerViewport = new Point(MapInstance.AsFrameworkElement.ActualWidth / 2, MapInstance.AsFrameworkElement.ActualHeight / 2);
            //    Location center = MapInstance.ViewportPointToLocation(centerViewport);
            //    Point logical = CoordinateTransformation.GeographicToLogical(center);

            //    // at the currentWorldwidth (currentworldwidth is the pixels that we'd need to show the entire world at this zoom level)
            //    // is there a complete map in the center of the screen?
            //    // If so favour that center map.
            //    double pixelsToMin180 = currentWorldWidthAtView * logical.X;
            //    double pixelsToMax180 = currentWorldWidthAtView * (1.0 - logical.X);

            //    if ((centerViewport.X - pixelsToMin180 > 0) && (centerViewport.X + pixelsToMax180 < MapInstance.AsFrameworkElement.ActualWidth))
            //    {
            //        topLeftAbsolutePixel.X -= DefaultWidth;
            //    }
            //}

            //this.targetXTranslate = -topLeftAbsolutePixel.X * currentScale;
            //this.targetYTranslate = -topLeftAbsolutePixel.Y * currentScale;

            #endregion

            SynchronizeOffsets();
            Point p = base.LocationToViewportPoint(new Location(BingMapsMaxLatitiude, -180));

            this.TargetXTranslate = p.X;
            this.TargetYTranslate = p.Y;
        }

        public override Point LocationToCelPixel(Location location)
        {
            Point logical = CoordinateTransformation.GeographicToLogical(location);

            return new Point
            {
                X = this.Width * logical.X,
                Y = this.Width * logical.Y
            };
        }
    }
}
